using LiJ.Common.Core;
using LiJ.Common.Extention;
using LiJ.Common.Plugs.CachePlug;
using LiJ.Http.Mos;
using LiJ.Framework.Official.Agent.Mos;
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace LiJ.Framework.Official
{
	/// <summary>
	///  微信开放平台相关接口基类
	/// </summary>
	public class WxAgentBaseApi : WxBaseApi
	{
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="config"></param>
		public WxAgentBaseApi(AppConfig config)
			: base(config)
		{
		}

		/// <summary>
		///   获取公众号的AccessToken
		///     【首先从缓存中获取，如果没有再从远程获取】
		/// </summary>
		/// <returns></returns>
		public async Task<WxGetAgentAccessTokenResp> GetAgentAccessTokenFromCacheAsync()
		{
			string m_OffcialAccessTokenKey = string.Format("social_wx_offcial_agent_accesstoken_{0}", base.ApiConfig.AppId);
			WxGetAgentAccessTokenResp wxGetAgentAccessTokenResp = CacheUtil.Get<WxGetAgentAccessTokenResp>(m_OffcialAccessTokenKey, base.ModuleName);
			if (wxGetAgentAccessTokenResp != null && wxGetAgentAccessTokenResp.expires_date >= DateTime.Now.ToUtcSeconds())
			{
				return wxGetAgentAccessTokenResp;
			}
			wxGetAgentAccessTokenResp = await this.GetAgentAccessTokenFromWxAsync();
			if (!wxGetAgentAccessTokenResp.IsSuccess())
			{
				return wxGetAgentAccessTokenResp;
			}
			wxGetAgentAccessTokenResp.expires_date = DateTime.Now.ToUtcSeconds() + wxGetAgentAccessTokenResp.expires_in - 600;
			CacheUtil.AddOrUpdate(m_OffcialAccessTokenKey, wxGetAgentAccessTokenResp, TimeSpan.FromSeconds((double)(wxGetAgentAccessTokenResp.expires_in - 600)), null, base.ModuleName);
			return wxGetAgentAccessTokenResp;
		}

		/// <summary>
		/// 从微信服务器获取AccessToken，请注意访问速率控制，正常情况请访问： 【GetAgentAccessTokenFromCacheAsync】
		/// </summary>
		/// <returns></returns>
		public async Task<WxGetAgentAccessTokenResp> GetAgentAccessTokenFromWxAsync()
		{
			Func<AppConfig, string> agentVerifyTicketGetFunc = WxOfficialConfigProvider.AgentVerifyTicketGetFunc;
			string value = (agentVerifyTicketGetFunc != null) ? agentVerifyTicketGetFunc(base.ApiConfig) : null;
			if (string.IsNullOrEmpty(value))
			{
				throw new ArgumentNullException("verifyticket", "verifyticket未发现，请检查 WxOfficialConfigProvider 下 AgentVerifyTicketGetFunc 委托是否为空或者返回值不正确！");
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{\"component_appid\":\"").Append(base.ApiConfig.AppId).Append("\",");
			stringBuilder.Append("\"component_appsecret\":\"").Append(base.ApiConfig.AppSecret).Append("\",");
			stringBuilder.Append("\"component_verify_ticket\":\"").Append(value).Append("\" }");
			LHttpRequest request = new LHttpRequest
			{
				AddressUrl = string.Format("{0}/cgi-bin/component/api_component_token", "https://api.weixin.qq.com"),
				HttpMothed = HttpMothed.Post,
				CustomBody = stringBuilder.ToString()
			};
			return await base.RestCommonJson<WxGetAgentAccessTokenResp>(request, null);
		}

		/// <summary>
		///   第三方代理平台的请求方法
		///      预处理component_access_token赋值
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="req"></param>
		/// <param name="client">自定义 HttpClient </param>
		/// <returns></returns>
		protected async Task<T> RestCommonAgentAsync<T>(LHttpRequest req, HttpClient client = null) where T : WxBaseResp, new()
		{
			WxGetAgentAccessTokenResp wxGetAgentAccessTokenResp = await this.GetAgentAccessTokenFromCacheAsync();
			if (!wxGetAgentAccessTokenResp.IsSuccess())
			{
				return ResultMoMap.ConvertToResult<T>((ResultMo)wxGetAgentAccessTokenResp);
			}
			req.AddressUrl = req.AddressUrl + "?component_access_token=" + wxGetAgentAccessTokenResp.component_access_token;
			return await base.RestCommonJson<T>(req, client);
		}
	}
}
